package presentation;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

import org.jdesktop.swingx.JXMapKit;
import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.mapviewer.DefaultTileFactory;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.jdesktop.swingx.mapviewer.TileFactoryInfo;
import org.jdesktop.swingx.mapviewer.Waypoint;
import org.jdesktop.swingx.mapviewer.WaypointPainter;
import org.jdesktop.swingx.mapviewer.WaypointRenderer;

import control.CActioner;
import control.TaxaFactory;
import control.connector.Taxa;
import control.connector.TaxaObserver;
import control.connector.ImageMap;

/**
 * @author   Martin D Hansen, Jens Riise Danielsen, Alexander Poopeiko
 */
public class PMapPanel extends JPanel implements TaxaObserver{
	
	//test route
	private double[][] route1 = new double[14][2];
	
	//index to control the movement in test route
	private int taxiMoved = 0;
	
	//The holder of the images
	public ImageMap[] imageHolder = new ImageMap[5];
	
	//Index number of next position to add a map 
	private int imageCounter = 0;
	
	//The names of the maps
	private String[] mapNames = new String[imageHolder.length];
	
	//Combo box to choose the images
	private JComboBox chooseImage;
	
	//The menu panel
	private JPanel menuPanel;
	/**
	 * @uml.property  name="placeOrderDialog"
	 * @uml.associationEnd  
	 */

	/**
	 * @uml.property  name="map"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private ImageMap map;
	/**
	 * @uml.property  name="waypointR"
	 * @uml.associationEnd  readOnly="true"
	 */
	private WaypointRenderer waypointR;
	/**
	 * @uml.property  name="g"
	 */
	private java.awt.Graphics2D g;
//	private Map<Waypoint, Taxa> taxaWaypoints;
	private Map<Waypoint, Taxa> taxaWaypoints; //TODO Test if this code works
	private WaypointPainter painter;
	
	
	public PMapPanel() throws IOException{
		setLayout(new BorderLayout());
		
		menuPanel = new JPanel();
		menuPanel.setBorder(BorderFactory.createTitledBorder("Menu"));
		menuPanel.setPreferredSize(new Dimension(175,400));
		
		// Is used to count the maps, so we know where in the array to add new maps. 
		imageCounter=0;
		
		
		//moving test-positions:
		route1[0][0] = 55.39763232472325;
		route1[0][1] = 10.366368981612448;
		route1[1][0] = 55.39779118081181;
		route1[1][1] = 10.370990509193776;
		route1[2][0] = 55.398363062730624;
		route1[2][1] = 10.374570565770863;
		route1[3][0] = 55.399395627306276;
		route1[3][1] = 10.379387369165489;
		route1[4][0] = 55.39996750922509;
		route1[4][1] = 10.381730678925035;
		route1[5][0] = 55.40093653136531;
		route1[5][1] = 10.379843012729845;
		route1[6][0] = 55.402366236162365;
		route1[6][1] = 10.378020438472419;
		route1[7][0] = 55.40358942804428;
		route1[7][1] = 10.378020438472419;
		route1[8][0] = 55.404256623616234;
		route1[8][1] = 10.381340127298444;
		route1[9][0] = 55.405273302583026;
		route1[9][1] = 10.385115459688826;
		route1[10][0] = 55.406941291512915;
		route1[10][1] = 10.3862871145686;
		route1[11][0] = 55.40921293357933;
		route1[11][1] = 10.38465981612447;
		route1[12][0] = 55.41037258302583;
		route1[12][1] = 10.377434611032532;
		route1[13][0] = 55.41151634686347;
		route1[13][1] = 10.369493394625177;

		
		//Move-the-taxi position
		JButton moveTaxi = new JButton("Opdater Taxi");
		moveTaxi.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				moveTaxa();
			}
		});
		
		menuPanel.add(moveTaxi);
		
		//Add a new image
		JButton newImage = new JButton("Nyt Billede");
		newImage.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent event) {
				newImage();
			}
		});
		menuPanel.add(newImage);
		
		//New button for changing current image
		JButton changeCurImage = new JButton("Change Image");
		changeCurImage.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event) {
				changeCurImage();
			}
		});
		menuPanel.add(changeCurImage);
		
		//The box containing the maps
		chooseImage = new JComboBox(mapNames);
		chooseImage.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event) {
				int index = chooseImage.getSelectedIndex();
				chooseImage(index);
			}
		});
		
		
		menuPanel.add(chooseImage);
		add(menuPanel,BorderLayout.WEST);
	}
	

	
	/**
	 * Moving the taxi within test coordinates
	 * 
	 */
	protected void moveTaxa(){
		imageHolder[curIndex].restoreImage();
		Graphics2D g2d = imageHolder[curIndex].getImage().createGraphics();
		
		// The taxi marker
		BufferedImage marker = null;
		try{
		marker = ImageIO.read(new File("src/marker.png"));
		} catch (IOException e){
			System.out.println(e);
		}
		
		//If taxi has reached the last coordinate, then reset
		if(taxiMoved == route1.length) taxiMoved = 0;
		  
		int[] pos = imageHolder[curIndex].gpsConvert(route1[taxiMoved][0], route1[taxiMoved][1]);
		
		
		g2d.drawImage(marker, pos[0], pos[1], this);
		
		
		taxiMoved++;
		
		imageHolder[curIndex].revalidate();
		imageHolder[curIndex].repaint();
		g2d.dispose();
	}
	
	/**
	 * Change the current map
	 * */
	protected void changeCurImage(){
		
		JFileChooser fc = new JFileChooser();
		fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fc.addChoosableFileFilter(new ImageFilter());
		fc.setAcceptAllFileFilterUsed(false);
		fc.setFileView(new ImageFileView());
		fc.showDialog(PMapPanel.this,"Choose Image");
		
		if(fc.getSelectedFile() != null){
			imageHolder[curIndex].changeFile(fc.getSelectedFile());
			imageHolder[curIndex].revalidate();
			imageHolder[curIndex].repaint();
		}
		 
	}
	
	// The current index we use.
	private int curIndex = 0;
	
	protected void chooseImage(int index){
		// Changes the map picture to the one which is chosen in the dropdown menu. 
		curIndex = index;
		this.remove(super.getComponentAt(700, 500));
		this.add(imageHolder[index],BorderLayout.CENTER);
		this.revalidate();
		this.repaint();
	}
	
	// We use this method to add new map pictures. Only PNG pictures are allowed. 
	protected void newImage(){
		
		JFileChooser fc = new JFileChooser("src");
		fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fc.addChoosableFileFilter(new ImageFilter());
		fc.setAcceptAllFileFilterUsed(false);
		fc.setFileView(new ImageFileView());
		fc.showDialog(this,"Choose image");
		
		File file = fc.getSelectedFile();
		// We move one place forward. 
		imageCounter++;
		imageHolder[imageCounter-1] = new ImageMap(file);

		menuPanel.remove(chooseImage);
		mapNames[imageCounter-1] = file.getName();
		
		chooseImage = new JComboBox(mapNames);
		chooseImage.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent event) {
				int index = chooseImage.getSelectedIndex();
				
				chooseImage(index);
			}
		});
		
		menuPanel.add(chooseImage);
		
		chooseImage.revalidate();
		chooseImage.repaint();			
		
		for(int i = 0; i < imageHolder.length; i++){
			if (imageHolder[i] != null) System.out.println(imageHolder[i].getName());
		}
	}
	


	public void updateTaxis() {
		List<Taxa> taxis = TaxaFactory.getAllTaxis();
		taxaWaypoints.clear();
		for(Taxa taxa : taxis){
			taxaWaypoints.put(new Waypoint(taxa.getLatitude(),taxa.getLongtitude()), taxa);
			taxaWaypoints.put(new Waypoint(taxa.getLatitude(), taxa.getLongtitude()), taxa);
		}
	}
}
